package org.keyyond.ms.business.service.impl;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.keyyond.ms.business.common.CommonService;
import org.keyyond.ms.business.dao.MsBusinessMessageLogDao;
import org.keyyond.ms.business.dao.MsBusinessParamDao;
import org.keyyond.ms.business.model.MsBusinessMessageLog;
import org.keyyond.ms.business.model.MsBusinessParam;
import org.keyyond.ms.business.model.vo.MsBusinessMessageLogVo;
import org.keyyond.ms.business.service.MsBusinessMessageLogService;
import org.keyyond.ms.business.util.Constant;
import org.keyyond.ms.core.exception.FDFBexception;
import org.keyyond.ms.core.util.DateUtil;
import org.keyyond.ms.core.util.JsonUtil;
import org.keyyond.ms.core.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MsBusinessMessageLogServiceImpl extends CommonService implements MsBusinessMessageLogService {
	private static Logger logger = Logger.getLogger(MsBusinessMessageLogServiceImpl.class);
	
	@Autowired
	private MsBusinessMessageLogDao messageLogDao;
	
	@Autowired
	private MsBusinessParamDao paramDao;

	private static final int CONST_CONTENT_LENGTH = 1024;
	private static final int CONST_RETURN_MESSAGE_LENGTH = 2048;
	
	@Override
	public String addSmsMessageLog(String param) {
		try {
			//判断是否为空
			if(StringUtils.isEmpty(param) || param.equals("{}")) return "{\"fail\":\"失败,传入的参数为空\"}";
//			//处理Json字符串的value带Json字符串的情况
//			int i = 1;//保存查找的下标
//			while(true){
//				if(jsonStr.indexOf("{", i) > 0){
//					int index = jsonStr.indexOf("}", jsonStr.indexOf("{", i));
//					//获得Content内容
//					String contentVal = jsonStr.substring(jsonStr.indexOf("{", i), index + 1);
//					String val = contentVal.replaceAll("\"", "");
//					//替换Content
//					jsonStr.replace(contentVal,val);
//					i = index;
//				}else break;
//			}
			//将Json对象转化为JavaBean对象
			MsBusinessMessageLog messageLog = JsonUtil.readJson2Bean(param,MsBusinessMessageLog.class);
			if(messageLog == null) throw new FDFBexception("将传入的Json字符串转换成Bean失败");
			//调用校验属性值的方法
			String checkStr = checkAddSmsMessageLogData(messageLog);
			messageLog.setReturnmessage(StringUtil.cutString(messageLog.getReturnmessage(), CONST_RETURN_MESSAGE_LENGTH, "GBK"));//截取return message长度
			if(!StringUtils.isEmpty(checkStr)) return "{\"fail\":\"失败,"+ checkStr +"\"}";
			//调用数据层添加的方法
			messageLogDao.insert(messageLog);
			return "{\""+ messageLog.getSeqno() +"\":\"成功\"}";
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("参数:" + param + ">>>添加日志信息失败>>>" + e.getMessage());
			//记录日志
			MsBusinessMessageLog messageLog = new MsBusinessMessageLog();
			messageLog.setLogtype(Constant.CONST_LOGTYPE_EXCEPTION);
			messageLog.setContent(StringUtils.isEmpty(param) ? "" : StringUtil.cutString(param, CONST_CONTENT_LENGTH, "GBK"));//截取长度,推送参数
			messageLog.setReturnmessage(StringUtil.cutString(e.getMessage(), CONST_RETURN_MESSAGE_LENGTH, "GBK"));//截取长度,返回消息
			messageLog.setCreateby(Constant.CONST_SYSTEM);//创建人
			messageLog.setModifyby(Constant.CONST_SYSTEM);//修改人
			try {
				messageLogDao.insert(messageLog);//调用Dao层添加日志的方法
			} catch (Exception e2) {
				e2.printStackTrace();
				logger.error("添加日志信息发生异常后添加日志失败>>>" + e2.getMessage());
			}
			return "{\"exception\":\"" + e.getMessage() + "\"}";
		}
	}

	@Override
	public String getSelectListByPage(HttpServletRequest request,String param) {
		try {
			//回执的Json
			String resultJosn = null;
			//判断是否为空
			if(StringUtils.isEmpty(param) || param.equals("{}")) resultJosn = "[]";
			//判断微服务跟踪ID是否为空
			if(request == null) throw new FDFBexception("请求对象request为Null");
			String traceId = request.getHeader("X-B3-TraceId");
			if(StringUtils.isEmpty(traceId)) throw new FDFBexception("微服务跟踪ID为Null");
			//判断回执的Json是否为Null,不为Null则不查询
			if(resultJosn == null){
				//将Json对象转化为JavaBean对象
				MsBusinessMessageLog messageLogParam =  JsonUtil.readJson2Bean(param,MsBusinessMessageLog.class);
				if(messageLogParam == null) throw new FDFBexception("将传入的Json字符串转换成Bean失败");
				//检验开始页与结束页是否有值
				if(messageLogParam.getStartpage() <= 0 || 
						messageLogParam.getPagesize() <= 0) throw new FDFBexception("开始页或页大小<=0");
				//校验日期格式
				if(!StringUtils.isEmpty(messageLogParam.getBegindate()) && 
						!DateUtil.checkStrFormat(messageLogParam.getBegindate()))
				{
					throw new FDFBexception("开始日期不合法或格式错误,正确格式yyyy-MM-dd");
				}
				if(!StringUtils.isEmpty(messageLogParam.getEnddate()) && 
						!DateUtil.checkStrFormat(messageLogParam.getEnddate()))
				{
					throw new FDFBexception("结束日期不合法或格式错误,正确格式yyyy-MM-dd");
				}
				//调用Dao层分页查询的方法
				List<MsBusinessMessageLog> list = messageLogDao.selectListByPage(messageLogParam,
						messageLogParam.getStartpage(),messageLogParam.getPagesize());
				//保存最终要返回的数据
				List<MsBusinessMessageLogVo> listVos = new ArrayList<MsBusinessMessageLogVo>();
				//将Bean转化为Vo
				for(MsBusinessMessageLog msbusinessmessagelog : list){
					MsBusinessMessageLogVo msbusinessmessagelogvo = new MsBusinessMessageLogVo();
					msbusinessmessagelogvo = (MsBusinessMessageLogVo) copyBean(msbusinessmessagelog, msbusinessmessagelogvo);
					listVos.add(msbusinessmessagelogvo);
				}
				//将分页查询的结果List转化成Json对象
				try {
					JSONArray jsonArray = JSONArray.fromObject(listVos);
					resultJosn = jsonArray.toString();
				} catch (Exception e) {
					e.printStackTrace();
					throw new FDFBexception("将查询出的List转换成Json失败" + e.getMessage());
				}
			}
			//记录日志
			MsBusinessMessageLog messageLog = new MsBusinessMessageLog();
			messageLog.setLogtype(Constant.CONST_LOGTYPE_SERVICE_CALL);//日志类型
			messageLog.setContent(StringUtils.isEmpty(param) ? "" : StringUtil.cutString(param, CONST_CONTENT_LENGTH, "GBK"));//截取长度,推送参数
			messageLog.setReturnmessage(StringUtil.cutString(resultJosn, CONST_RETURN_MESSAGE_LENGTH, "GBK"));//截取长度,返回消息
			messageLog.setTraceid(traceId);//微服务跟踪ID
			messageLog.setCreateby(Constant.CONST_SYSTEM);//创建人
			messageLog.setModifyby(Constant.CONST_SYSTEM);//修改人
			try {
				messageLogDao.insert(messageLog);//调用Dao层添加日志的方法
			} catch (Exception e) {
				e.printStackTrace();
				throw new FDFBexception("分页查询日志信息成功后添加日志失败>>>" + e.getMessage());
			}
			return resultJosn;
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("参数:" + param + ">>>分页查询日志信息失败>>>" + e.getMessage());
			//记录日志
			MsBusinessMessageLog messageLog = new MsBusinessMessageLog();
			messageLog.setLogtype(Constant.CONST_LOGTYPE_EXCEPTION);
			messageLog.setContent(StringUtils.isEmpty(param) ? "" : StringUtil.cutString(param, CONST_CONTENT_LENGTH, "GBK"));//截取长度,推送参数
			messageLog.setReturnmessage(StringUtil.cutString(e.getMessage(), CONST_RETURN_MESSAGE_LENGTH, "GBK"));//截取长度,返回消息
			messageLog.setCreateby(Constant.CONST_SYSTEM);//创建人
			messageLog.setModifyby(Constant.CONST_SYSTEM);//修改人
			try {
				messageLogDao.insert(messageLog);//调用Dao层添加日志的方法
			} catch (Exception e2) {
				e2.printStackTrace();
				logger.error("分页查询日志信息发生异常后添加日志失败>>>" + e2.getMessage());
			}
			return "[]";
		}
	}
	
	@Override
	public String canUserResetPassword(HttpServletRequest request, String param) {
		MsBusinessMessageLog messageLog = new MsBusinessMessageLog();	
		messageLog.setCreateby(Constant.CONST_SYSTEM_LOG_CREATEON);
		messageLog.setModifyby(Constant.CONST_SYSTEM_LOG_MODIFYON);
		JSONObject result = new JSONObject();
		try {
			String traceId = request.getHeader("X-B3-TraceId");
			if(StringUtils.isEmpty(traceId)) throw new FDFBexception("微服务跟踪ID为Null");
			messageLog.setTraceid(traceId);
			messageLog.setLogtype(Constant.CONST_LOGTYPE_SERVICE_CALL);
			if(StringUtils.isEmpty(param) || param.equals("{}")) {
				messageLog.setContent(param);
				result.put(Constant.CONST_CHECK_RESULT_RESULT, Constant.CONST_CHECK_RESULT_FAIL);
			}else {
				Map<String,String> paramMap = JsonUtil.JsonToMap(param);
				if(null != paramMap) {
					if(StringUtil.checkMobilePhoneNumber(paramMap.get("mobile"))) {
						messageLog.setPhonenumber(paramMap.get("mobile"));
						if(!StringUtils.isEmpty(paramMap.get("codeType"))) {
							messageLog.setSendtype(paramMap.get("codeType"));
							if(checkCount(paramMap.get("mobile"), paramMap.get("codeType"))) {
								result.put(Constant.CONST_CHECK_RESULT_RESULT, Constant.CONST_CHECK_RESULT_SUCCESS);
								messageLog.setReturnmessage(Constant.CONST_CHECK_RESULT_SUCCESS);
							}else {
								result.put(Constant.CONST_CHECK_RESULT_RESULT, Constant.CONST_CHECK_RESULT_FAIL);
								messageLog.setReturnmessage(Constant.CONST_CHECK_RESULT_FAIL);
							}			
						}else {
							result.put(Constant.CONST_CHECK_RESULT_RESULT, Constant.CONST_CHECK_RESULT_FAIL);
							messageLog.setReturnmessage(Constant.CONST_CHECK_RESULT_FAIL);
						}
									
					}else {
						result.put(Constant.CONST_CHECK_RESULT_RESULT, Constant.CONST_CHECK_RESULT_MOBILEERROR);
						messageLog.setReturnmessage(Constant.CONST_CHECK_RESULT_MOBILEERROR);
					}
					
				}else {
					result.put(Constant.CONST_CHECK_RESULT_RESULT, Constant.CONST_CHECK_RESULT_FAIL);
					messageLog.setReturnmessage(Constant.CONST_CHECK_RESULT_FAIL);
				}				
			}
			messageLogDao.insert(messageLog);
			return result.toString();
		}catch(Exception e) {
			e.printStackTrace();
			result.put(Constant.CONST_CHECK_RESULT_RESULT, Constant.CONST_CHECK_RESULT_EXCEPTION);
			messageLog.setReturnmessage(Constant.CONST_CHECK_RESULT_EXCEPTION);
			messageLog.setLogtype(Constant.CONST_LOGTYPE_EXCEPTION);
			messageLogDao.insert(messageLog);
			return result.toString();
		}		
	}
	
	public boolean checkCount(String phone, String type) {
		boolean result = true;
		int count = 0;
		String date = DateUtil.formatDate(new Date());
		Map<String, String> map = new HashMap<String, String>();
		map.put("returncode", Constant.CONST_CHECK_RESULT_STATUS_OK);
		map.put("sendtype", type);
		map.put("phonenumber", phone);
		if(Constant.CONST_SENDTYPE_AUTH_CODE.equals(type))
		{
			MsBusinessParam loginParam = paramDao.selectByCode(Constant.CONST_SYSTEM_PARAM_LOGIN);
			if(null!= loginParam) {
				map.put("date", date);
				count = messageLogDao.getSendCount(map);
				result = count<Integer.parseInt(loginParam.getPaValue())?true:false;
			}else{
				result = false;
			}
		}
		else if(Constant.CONST_SENDTYPE_INFORM.equals(type))
		{
			MsBusinessParam noticeParam = paramDao.selectByCode(Constant.CONST_SYSTEM_PARAM_NOTICE);
			if(null != noticeParam) {
				map.put("date", date);
				count = messageLogDao.getSendCount(map);
				result = count<Integer.parseInt(noticeParam.getPaValue())?true:false;
			}else {
				result = false;
			}
		}
		else if(Constant.CONST_SENDTYPE_RESET_PASSWORD.equals(type))
		{
			MsBusinessParam resetParam = paramDao.selectByCode(Constant.CONST_SYSTEM_PARAM_RESET);
			if(null != resetParam) {
				String[] sum = resetParam.getPaValue().split(",");
				map.put("date", date);
				count = messageLogDao.getSendCount(map);
				if(count<Integer.parseInt(sum[0])) {
					map.put("date", date.substring(0, 7));
					count = messageLogDao.getSendCount(map);
					if(count<Integer.parseInt(sum[1])) {
						map.put("date", date.substring(0, 4));
						count = messageLogDao.getSendCount(map);
						if(count<Integer.parseInt(sum[2])) {
							result = true;
						}else {
							result = false;
						}
					}else {
						result = false;
					}
				}else {
					result = false;
				}
			}else {
				result = false;
			}
		}
		else if(Constant.CONST_SENDTYPE_REGIST_CODE.equals(type))
		{
			MsBusinessParam registParam = paramDao.selectByCode(Constant.CONST_SYSTEM_PARAM_REGISTER);
			if(null != registParam) {
				String[] sum = registParam.getPaValue().split(",");
				map.put("date", date);
				count = messageLogDao.getSendCount(map);
				if(count<Integer.parseInt(sum[0])) {
					map.put("date", date.substring(0, 7));
					count = messageLogDao.getSendCount(map);
					if(count<Integer.parseInt(sum[1])) {
						map.put("date", date.substring(0, 4));
						count = messageLogDao.getSendCount(map);
						if(count<Integer.parseInt(sum[2])) {
							result = true;
						}else {
							result = false;
						}
					}else {
						result = false;
					}
				}else {
					result = false;
				}
			}else {
				result = false;
			}	
		}
		else if(Constant.CONST_SENDTYPE_MAIL_PASSWORD_CODE.equals(type))
		{
			MsBusinessParam mailParam = paramDao.selectByCode(Constant.CONST_SYSTEM_PARAM_MAIL_PASSWORD);
			if(null != mailParam) {
				if(Constant.CONST_SYSTEM_SENDMESSAGE_COUNT.equals(mailParam.getPaValue())) {
					return true;
				}
				map.put("date", date);
				count = messageLogDao.getSendCount(map);
				result = count<Integer.parseInt(mailParam.getPaValue())?true:false;
			}else {
				result = false;
			}	
		}
		else
		{
			return false;
		}
		return result;
	}
	
	/**
	 * 校验添加的日志属性值
	 * @author zhuyong
	 * @param messageLog 日志对象
	 * @return 校验消息
	 * @throws FDFBexception 
	 */
	public String checkAddSmsMessageLogData(MsBusinessMessageLog messageLog) throws FDFBexception{
		try {
			//验证日志类型字段
			if(StringUtils.isEmpty(messageLog.getLogtype())){
			    return "日志类型字段为空";
			} 
			if(messageLog.getLogtype().getBytes("GBK").length > 2){
			    return "日志类型字段超长最高长度为2";
			} 
//			//保存所有的日志类型
//			String logtypeStr = Constant.CONST_LOGTYPE_SMS + ","+
//					Constant.CONST_LOGTYPE_EXCEPTION + "," + 
//					Constant.CONST_LOGTYPE_LOGIN + "," + Constant.CONST_LOGTYPE_SERVICE_CALL;
//			if(!logtypeStr.contains(messageLog.getLogtype()) ||
//					messageLog.getLogtype().equals(",")){
//			    return "日志类型字段的值超出范围";
//			} 
			//验证手机号字段
			if(StringUtils.isEmpty(messageLog.getPhonenumber()) && 
					messageLog.getLogtype().equals(Constant.CONST_LOGTYPE_SMS)) {
			    return "手机号字段为空";
			}
			if(!StringUtils.isEmpty(messageLog.getPhonenumber()) && 
					messageLog.getPhonenumber().getBytes("GBK").length > 20){
			    return "手机号字段超长最高长度为20";
			} 
			if(!StringUtils.isEmpty(messageLog.getPhonenumber())
					&& !StringUtil.checkMobilePhoneNumber(messageLog.getPhonenumber()) && 
					messageLog.getLogtype().equals(Constant.CONST_LOGTYPE_SMS)){
			    return "手机号不合法";
			} 
			//验证推送参数字段
			if(StringUtils.isEmpty(messageLog.getContent()) &&
					messageLog.getLogtype().equals(Constant.CONST_LOGTYPE_SMS)){
			    return "推送参数字段为空";
			} 
			if(!StringUtils.isEmpty(messageLog.getContent()) && 
					messageLog.getContent().getBytes("GBK").length > CONST_RETURN_MESSAGE_LENGTH){
			    String str = messageLog.getContent();
			    messageLog.setContent(StringUtil.subStringByBytes(str, CONST_RETURN_MESSAGE_LENGTH, "GBK"));
			} 
			//验证回执编码字段
			if(StringUtils.isEmpty(messageLog.getReturncode()) && 
					messageLog.getLogtype().equals(Constant.CONST_LOGTYPE_SMS)){
			    return "回执编码字段为空";
			}
			if(!StringUtils.isEmpty(messageLog.getReturncode()) && 
					messageLog.getReturncode().getBytes("GBK").length > 40) {
			    return "回执编码字段超长最高长度为40";
			}
			//验证回执信息字段
			if(StringUtils.isEmpty(messageLog.getReturnmessage())){
			    return "回执信息字段为空";
			} 
			if(messageLog.getReturnmessage().getBytes("GBK").length > CONST_RETURN_MESSAGE_LENGTH) {
			    String str = messageLog.getReturnmessage();
			    messageLog.setReturnmessage(StringUtil.subStringByBytes(str, CONST_RETURN_MESSAGE_LENGTH, "GBK"));
			}
			//验证请求ID字段
			if(StringUtils.isEmpty(messageLog.getRequestid()) && 
					messageLog.getLogtype().equals(Constant.CONST_LOGTYPE_SMS)){
			    return "请求ID字段为空";
			} 
			if(!StringUtils.isEmpty(messageLog.getRequestid()) && 
					messageLog.getRequestid().getBytes("GBK").length > 40){
			    return "请求ID字段超长最高长度为40";
			} 
			//验证回执ID字段
			if(StringUtils.isEmpty(messageLog.getBizid()) && 
					messageLog.getLogtype().equals(Constant.CONST_LOGTYPE_SMS)) {
			    return "回执ID字段为空";
			}
			if(!StringUtils.isEmpty(messageLog.getBizid()) && 
					messageLog.getBizid().getBytes("GBK").length > 40) {
			    return "回执ID字段超长最高长度为40";
			}
			//验证推送类型字段
			if(StringUtils.isEmpty(messageLog.getSendtype()) && 
					messageLog.getLogtype().equals(Constant.CONST_LOGTYPE_SMS)) {
			    return "推送类型字段为空";
			}
			if(!StringUtils.isEmpty(messageLog.getSendtype()) && 
					messageLog.getSendtype().getBytes("GBK").length > 2) {
			    return "推送类型字段超长最高长度为2";
			}
			/**
			 * 此日志服务之前不能共用，为了共用注释了以下代码
			 */
			//保存所有的推送类型
//			String sendtypeStr = Constant.CONST_SENDTYPE_AUTH_CODE + ","+
//					Constant.CONST_SENDTYPE_INFORM + "," + 
//					Constant.CONST_SENDTYPE_RESET_PASSWORD + "," + Constant.CONST_SENDTYPE_REGIST_CODE + "," + Constant.CONST_SENDTYPE_EMAIL_PASSWORD;
//			if(!StringUtils.isEmpty(messageLog.getSendtype()) && 
//					(!sendtypeStr.contains(messageLog.getSendtype()) ||
//					messageLog.getSendtype().equals(","))) return "推送类型字段的值超出范围";
			//验证微服务跟踪ID字段
			if(messageLog.getLogtype().equals(Constant.CONST_LOGTYPE_SERVICE_CALL) && 
					StringUtils.isEmpty(messageLog.getTraceid())) {
			    return "微服务跟踪ID字段为空";
			}
			if(!StringUtils.isEmpty(messageLog.getTraceid()) && 
					messageLog.getTraceid().getBytes("GBK").length > 40) {
			    return "微服务跟踪ID字段超长最高长度为40";
			}
			//验证创建人字段
			if(StringUtils.isEmpty(messageLog.getCreateby())) {
			    return "创建人字段为空";
			}
			if(messageLog.getCreateby().getBytes("GBK").length > 40) {
			    return "创建人字段超长最高长度为40";
			}
			//验证修改人字段
			if(StringUtils.isEmpty(messageLog.getModifyby())) {
			    return "修改人字段为空";
			}
			if(messageLog.getModifyby().getBytes("GBK").length > 40) {
			    return "修改人字段超长最高长度为40";
			}			
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			logger.error("添加日志时校验日志对象属性值失败" + e.getMessage());
			throw new FDFBexception("添加日志时校验日志对象属性值失败" + e.getMessage());
		}
		return null;
	}

	@Override
	public int saveLog(MsBusinessMessageLog businessMessageLog) {
		// TODO Auto-generated method stub
		return messageLogDao.insert(businessMessageLog);
	}
	
}
